import 'dart:convert';
import 'package:x3_base_core/x3_base_core.dart';

import 'base_utils.dart';
import 'package:event_bus/event_bus.dart';
import 'package:x3_base_core/base_models/base_http_error_model.dart';

class BaseDioCodeUtil {
  BaseDioCodeUtil._();

  /// 自定义错误码-网络异常
  static const int network_error_code = -1;

  /// 自定义错误码-网络链接超时
  static const int network_timeout_code = -2;

  /// 自定义错误码-界面上的消息提示
  static const int toast_code = -3;

  /// Http请求错误码-错误请求,请求参数有误
  static const code_400 = 400;

  /// Http请求错误码-未授权，访问被拒绝
  static const code_401 = 401;

  /// Http请求错误码-需要付费
  static const code_402 = 402;

  /// Http请求错误码-身份认证已失效,请重新登陆
  static const code_403 = 403;

  /// Http请求错误码-未找到，服务器找不到指定的资源，文档不存在
  static const code_404 = 404;

  /// Http请求错误码-方法不允许，请求方法（GET、POST、HEAD、Delete、PUT、TRACE等）对指定的资源不适用，用来访问本页面的 HTTP 谓词不被允许（方法不被允许）
  static const code_405 = 405;

  /// Http请求错误码-不接受，请求的资源的内容特性无法满足请求头中的条件，因而无法生成响应实体
  static const code_406 = 406;

  /// Http请求错误码-需要代理认证，与401响应类似，只不过客户端必须在代理服务器上进行身份验证。代理服务器必须返回一个 Proxy-Authenticate 用以进行身份询问
  static const code_407 = 407;

  /// Http请求错误码-请求超时，客户端没有在服务器预备等待的时间内完成一个请求的发送。客户端可以随时再次提交这一请求而无需进行任何更改
  static const code_408 = 408;

  /// Http请求错误码-冲突，通常和PUT请求有关。由于请求和资源的当前状态相冲突，因此请求不能成功
  static const code_409 = 409;

  /// Http请求错误码-失败，被请求的资源在服务器上已经不再可用，而且没有任何已知的转发地址。这样的状况应当被认为是永久性的
  static const code_410 = 410;

  /// Http请求错误码-需要长度，服务器拒绝在没有定义 Content-Length 头的情况下接受请求
  static const code_411 = 411;

  /// Http请求错误码-前提条件失败，服务器在验证在请求的头字段中给出先决条件时，没能满足其中的一个或多个
  static const code_412 = 412;

  /// Http请求错误码-请求实体太长，服务器拒绝处理当前请求，因为该请求提交的实体数据大小超过了服务器愿意或者能够处理的范围
  static const code_413 = 413;

  /// Http请求错误码-请求URI太长，请求的URI 长度超过了服务器能够解释的长度
  static const code_414 = 414;

  /// Http请求错误码-页眉指定了未实现的配置，服务器不支持当前请求所需要的某个功能
  static const code_501 = 501;

  /// Http请求错误码-网关失败，作为网关或者代理工作的服务器尝试执行请求时，从上游服务器接收到无效的响应
  static const code_502 = 502;

  /// Http请求错误码-服务不可用，服务器由于维护或者负载过重未能应答
  static const code_503 = 503;

  /// Http请求错误码-网关超时，作为网关或者代理工作的服务器尝试执行请求时，未能及时从上游服务器或者辅助服务器收到响应
  static const code_504 = 504;

  /// Http请求错误码-服务器不支持请求中所指明的HTTP版本
  static const code_505 = 505;

  /// 服务成功
  static const int success_code = 200;

  /// 事件订阅总栈
  static final EventBus eventBus = new EventBus();

  /// 发送错误信息
  static sendError(code, message, showToast) {
    if (showToast == true) {
      eventBus.fire(BaseHttpErrorModel(code, message));
    }
    return message;
  }

  static List<dynamic> decodeListResult(String data) {
    return json.decode(data);
  }

  static Map<String, dynamic> decodeMapResult(String data) {
    return json.decode(data);
  }

  static String encodeToString(String data) {
    return json.encode(data);
  }

  static List<Map<String, dynamic>> dynamicListToMapList(List<dynamic> data) {
    List<Map<String, dynamic>> items = <Map<String, dynamic>>[];
    for (var i = 0; i < data.length; i++) {
      Map<String, dynamic> item = data[i];
      items.add(item);
    }
    return items;
  }

  /// {"success":true,"data":"{\"data\":[]}"}
  /// 目前只解开以上数据，后续有需要再添加
  static dynamic getX3YjbServiceLastData(dynamic data, {bool showToast = false, String toastMsg = '请求失败'}) {
    if (data == null) return null;
    if (data is String && data.isEmpty) return '';
    if (data is Map) {
      String success = BaseUtils.getKeyData(data, 'success', defaultValue: 'false').toString();
      if (success == 'false' && toastMsg.isNotEmpty && showToast) {
        BaseUtils.showToast(toastMsg);
        return null;
      }
      // success == true
      var _data = BaseUtils.getKeyData(data, 'data');
      if (_data == null) return null;
      if (_data is String && _data.isEmpty) return null;
      if (_data is String) {
        try {
          var _dataJson = jsonDecode(_data);
          var jsonData = BaseUtils.getKeyData(_dataJson, 'data');
          return jsonData;
        } catch (e) {
          return null;
        }
      }
    }
    return null;
  }

  static dynamic getX2BusinessServiceLastData(BaseHttpResultModel resultModel){
    if(resultModel == null) return null;
    if(!resultModel.success || resultModel.data == null || !(resultModel.data is Map)) return null;
    String _status = BaseUtils.getKeyData(resultModel.data,'status',defaultValue: 'false').toString();
    if(_status != 'true') return null;
    if(!(resultModel.data as Map).containsKey('dataJson')) return null;
    if(!(resultModel.data['dataJson'] is Map)) return null;
    Map dataJson = resultModel.data['dataJson'];
    if(!dataJson.containsKey('data')) return null;
    return dataJson['data'];
  }
}
